Public Class OrderView
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents lblOrderNoText As System.Web.UI.WebControls.Label
    Protected WithEvents btnRemove As System.Web.UI.WebControls.Button
    Protected WithEvents btnBack As System.Web.UI.WebControls.Button
    Protected WithEvents btnArchived As System.Web.UI.WebControls.Button
    Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid
    Protected WithEvents tbEditForm As System.Web.UI.HtmlControls.HtmlTable
    Protected WithEvents tbCreatNewForm As System.Web.UI.HtmlControls.HtmlTable
    Protected WithEvents btnRefresh As System.Web.UI.WebControls.Button
    Protected WithEvents lblDepartureDate As System.Web.UI.WebControls.Label
    Protected WithEvents lblDestination As System.Web.UI.WebControls.Label
    Protected WithEvents lblFreightForwarder As System.Web.UI.WebControls.Label
    Protected WithEvents lblContainerNumber As System.Web.UI.WebControls.Label
    Protected WithEvents lblComments As System.Web.UI.WebControls.Label
    Protected WithEvents btnRemoveOI As System.Web.UI.WebControls.ImageButton
    Protected WithEvents btnEditOrder As System.Web.UI.WebControls.ImageButton
    Protected WithEvents btnSaveOrder As System.Web.UI.WebControls.ImageButton
    Protected WithEvents lblTitle As System.Web.UI.WebControls.Label
    Protected WithEvents lblPathName As System.Web.UI.WebControls.Label
    Protected WithEvents trEditOrder As System.Web.UI.HtmlControls.HtmlTableRow
    Protected WithEvents trViewOrder As System.Web.UI.HtmlControls.HtmlTableRow
    Protected WithEvents ddlPackingType As System.Web.UI.WebControls.DropDownList
    Protected WithEvents hidCustomerID As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents txtDestinationPort As System.Web.UI.WebControls.TextBox
    Protected WithEvents RequiredFieldValidator1 As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents hidDestinationPortID As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents txtSupplierCode As System.Web.UI.WebControls.TextBox
    Protected WithEvents reqvSupplierCode As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents hidSupplierID As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents txtSortRef As System.Web.UI.WebControls.TextBox
    Protected WithEvents reqvSortRef As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents hidSortRefID As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents txtSortRef2 As System.Web.UI.WebControls.TextBox
    Protected WithEvents Requiredfieldvalidator2 As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents hidSortRefID2 As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents radETAAsap As System.Web.UI.WebControls.RadioButton
    Protected WithEvents radETABefore As System.Web.UI.WebControls.RadioButton
    Protected WithEvents txtETABefore As System.Web.UI.WebControls.TextBox
    Protected WithEvents radETAAfter As System.Web.UI.WebControls.RadioButton
    Protected WithEvents txtETAAfter As System.Web.UI.WebControls.TextBox
    Protected WithEvents radETABetween As System.Web.UI.WebControls.RadioButton
    Protected WithEvents txtETAFrom As System.Web.UI.WebControls.TextBox
    Protected WithEvents txtETATo As System.Web.UI.WebControls.TextBox
    Protected WithEvents txtNoContainers As System.Web.UI.WebControls.TextBox
    Protected WithEvents ddlContainerType As System.Web.UI.WebControls.DropDownList
    Protected WithEvents comvContainerNo As System.Web.UI.WebControls.CompareValidator
    Protected WithEvents ddlOrderType As System.Web.UI.WebControls.DropDownList
    Protected WithEvents txtOrderNo As System.Web.UI.WebControls.TextBox
    Protected WithEvents reqvOrderNo As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents regvOrderNo As System.Web.UI.WebControls.RegularExpressionValidator
    Protected WithEvents ddlShippingType As System.Web.UI.WebControls.DropDownList
    Protected WithEvents txtOrderDate As System.Web.UI.WebControls.TextBox
    Protected WithEvents txtOrderBy As System.Web.UI.WebControls.TextBox
    Protected WithEvents reqvOrderBy As System.Web.UI.WebControls.RequiredFieldValidator
    Protected WithEvents txtGeneralShippingInstructions As System.Web.UI.WebControls.TextBox
    Protected WithEvents regvSI As System.Web.UI.WebControls.RegularExpressionValidator
    Protected WithEvents hidContactID As System.Web.UI.HtmlControls.HtmlInputHidden
    Protected WithEvents txtCustomerName As System.Web.UI.WebControls.TextBox
    Protected WithEvents lblErr As System.Web.UI.WebControls.Label
    Protected WithEvents btnPerRemove As System.Web.UI.WebControls.Button
    Protected WithEvents lblCreateNewOrder As System.Web.UI.WebControls.Label
    Protected WithEvents hrefOrderList As System.Web.UI.HtmlControls.HtmlAnchor
    Protected WithEvents btnAddOI As System.Web.UI.WebControls.ImageButton

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Protected WithEvents Header1 As Header

    Const ORDER_ITEM_SELECT_COLUMN_INDEX As Integer = 0
    Const ORDER_ITEM_EDIT_COLUMN_INDEX As Integer = 10

#Region "   Properties"
    Protected Property PageBO() As COrder
        Get
            Return CType(Session(OrderInput.ORDER_INPUT_PAGEBO_SESSION_NAME), COrder)
        End Get
        Set(ByVal Value As COrder)
            Session(OrderInput.ORDER_INPUT_PAGEBO_SESSION_NAME) = Value
        End Set
    End Property

    Protected Property UrlReferrer() As String
        Get
            Return CStr(ViewState("UrlReferrer"))
        End Get
        Set(ByVal Value As String)
            ViewState("UrlReferrer") = Value
        End Set
    End Property

    Private ReadOnly Property ReturnURL() As String
        Get
            If IsNothing(Request.QueryString("ru")) Then
                Return Me.UrlReferrer
            End If
            Return Server.UrlDecode(Request.QueryString("ru"))
        End Get
    End Property

#End Region

    Protected ReadOnly Property OrderID() As Integer
        Get
            Try
                If IsNothing(Request.QueryString("id")) Then
                    Return 0
                End If

                Dim id As Integer
                id = CInt(Request.QueryString("id"))

                If id < 0 Then
                    Throw New Exception
                End If

                Return id
            Catch ex As Exception
                Throw New ApplicationException("Invalid or missing parameter", ex)
            End Try
        End Get
    End Property

    Protected Function GetContactName() As String
        If PageBO.CustomerID > 0 AndAlso PageBO.OrderByCustomerID > 0 Then
            Dim objCusContact As New CCustomerContact
            Try
                objCusContact.Load(PageBO.OrderByCustomerID)
            Catch ex As Exception
                Throw New ApplicationException("Can not load customer name", ex)
            End Try

            'check for data integrity
            If objCusContact.CustomerID <> PageBO.CustomerID Then
                Throw New ApplicationException("Order data invalid, please check for customer id and customer's contact id")
            End If

            Return objCusContact.ContactName
        Else
            Return Nothing
        End If
    End Function

    Protected ReadOnly Property OrderCustomer() As CUser
        Get
            Dim customer As New CUser
            customer.Load(PageBO.CustomerID)

            Return customer
        End Get
    End Property

    Protected ReadOnly Property PageIsCustomer() As Boolean
        Get
            Return Security.IsCustomer
        End Get
    End Property

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not Page.IsPostBack Then

            If Security.IsCustomer Then
                Me.btnRemove.Visible = False
                Me.btnArchived.Visible = False
                Header1.MenuIndex = EMenuIndex.CustomerOrderList
                lblCreateNewOrder.Visible = False
                hrefOrderList.HRef = "../Customer/CusOrderList.aspx"

                Me.btnPerRemove.Visible = False
                Me.btnEditOrder.Visible = False
                Me.btnRemoveOI.Visible = False
                Me.btnAddOI.Visible = False

                DataGrid1.Columns(ORDER_ITEM_SELECT_COLUMN_INDEX).Visible = False
                DataGrid1.Columns(ORDER_ITEM_EDIT_COLUMN_INDEX).Visible = False
            Else
                Header1.MenuIndex = EMenuIndex.InternalOrderList
                lblCreateNewOrder.Visible = True
                hrefOrderList.HRef = "../Internal/OrderList.aspx"
            End If


            Dim obj As New COrder
            Try
                obj.Load(Me.OrderID)
            Catch ex As Exception
                Throw New ApplicationException("Failed to load data", ex)
            End Try

            Select Case CType(obj.Status, EOrderStatus)
                Case EOrderStatus.Archived
                    Me.btnArchived.Visible = False
                Case EOrderStatus.Removed
                    Me.btnRemove.Visible = False
                    Me.btnArchived.Visible = False
                    If Not Security.IsCustomer Then
                        Me.btnPerRemove.Visible = True
                    End If
            End Select

            If CType(obj.OrderType, EOrderType) = EOrderType.Bulk_Order Then
                Me.lblOrderNoText.Text = "BO Number"

                ' hide From BO# column
                Me.DataGrid1.Columns(Me.DataGrid1.Columns.Count - 1).Visible = False
            Else
                Me.lblOrderNoText.Text = "PO Number"
            End If

            PageBO = obj

            'Display the order's complete information if any.
            DisplayCompleteInformation()

            'Display all product items of this order.
            Me.DataGrid1.DataSource = PageBO.OrderItems
            Me.DataGrid1.DataBind()

            Me.UrlReferrer = Request.UrlReferrer.PathAndQuery


            Me.Header1.NavigationBar.Add("Back", Me.UrlReferrer)
        End If
    End Sub

    Private Sub DisplayCompleteInformation()

        If (PageBO.CompleteInfo) Then
            Me.lblDepartureDate.Text = MIMS_WRS.Business.Common.FormatDate(PageBO.DepartureDate)
            Me.lblDestination.Text = PageBO.Destination
            Me.lblFreightForwarder.Text = GetFreightForwarder(PageBO.FreightID)
            Me.lblContainerNumber.Text = PageBO.ContainerNumber
            Me.lblComments.Text = PageBO.Comments

            Me.tbCreatNewForm.Visible = False
            Me.tbEditForm.Visible = True
        End If
    End Sub

    Private Function GetFreightForwarder(ByVal freightID As Integer) As String
        Try
            Dim obj As New CLookupData
            obj.Load(freightID)

            Return obj.Value1
        Catch ex As Exception

            Return ""
        End Try
    End Function

    Protected Function GetRequestedETAText() As String
        Select Case CType(PageBO.RequestedETA, ERequestedETAType)
            Case ERequestedETAType.As_soon_as_possible
                Return CType(PageBO.RequestedETA, ERequestedETAType).ToString.Replace("_", " ")
            Case ERequestedETAType.After, ERequestedETAType.Before
                Return String.Format("{0} {1}", CType(PageBO.RequestedETA, ERequestedETAType).ToString, FormatDate(PageBO.ETADate1))
            Case ERequestedETAType.Between
                Return String.Format("Between {0} and {1}", FormatDate(PageBO.ETADate1), FormatDate(PageBO.ETADate2))
        End Select
    End Function

    Protected Function GetShippingTypeText() As String
        Return CType(PageBO.ShippingType, EShippingType).ToString.Replace("_", " ")
    End Function

    Protected Function GetPackingTypeText() As String
        Return CType(PageBO.PackingType, EPackingType).ToString.Replace("_", " ")
    End Function

    Protected Function GetContainerText() As String
        Return String.Format("{0} x {1}", PageBO.Containers, CType(PageBO.ContainerType, EContainerType).ToString.Replace("_", " "))
    End Function

    Protected Function GetAdjustedQuantityText(ByVal container As Object) As String
        If CBool(DataBinder.Eval(container, "DataItem.IsQuantityAdjusted")) = True Then
            Return CStr(DataBinder.Eval(container, "DataItem.AdjustedQuantity"))
        Else
            Return "N/A"
        End If
    End Function

    Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click
        Try
            PageBO.Status = EOrderStatus.Removed
            PageBO.UpdatedDate = Now
            PageBO.UpdatedBy = Security.GetCurrentUser.UsIdPk
            PageBO.Save()
            Response.Redirect(Me.ReturnURL)
        Catch ex As Exception
            Throw New ApplicationException("Error occurs when removing order", ex)
        End Try
    End Sub

    Private Sub btnPerRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPerRemove.Click
        Try
            ' Now permanently remove this order from database
            PageBO.PerRemoveOrder(PageBO.ID)
            Response.Redirect(Me.ReturnURL)
        Catch ex As Exception
            Throw New ApplicationException("Error occurs when removing order", ex)
        End Try
    End Sub

    Private Sub btnBack_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnBack.Click
        Response.Redirect(Me.ReturnURL)
    End Sub

    Private Sub btnArchived_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnArchived.Click
        Try

            PageBO.Status = EOrderStatus.Archived
            PageBO.UpdatedDate = Now
            PageBO.UpdatedBy = Security.GetCurrentUser.UsIdPk
            PageBO.Save()
            Response.Redirect(Me.ReturnURL)
        Catch ex As Exception
            Throw New ApplicationException("Error occurs when making archived order", ex)
        End Try
    End Sub

    Private Sub btnRefresh_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRefresh.Click
        'Response.Redirect(Request.Url.AbsoluteUri)
        PageBO.Load(PageBO.ID)

        DisplayCompleteInformation()
    End Sub

    Protected Function GetEditIndex(ByVal container As Object) As String
        Dim dgi As DataGridItem = CType(container, DataGridItem)
        Return String.Format("if (!btnEdit_onclick({0})) return false;", dgi.ItemIndex)
    End Function

    Protected Sub btnEdit_OnClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Me.DataGrid1.DataSource = PageBO.OrderItems
        Me.DataGrid1.DataBind()
    End Sub

    Private Sub btnRemoveOI_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnRemoveOI.Click
        Dim dgi As DataGridItem
        For Each dgi In Me.DataGrid1.Items
            Dim chk As HtmlInputCheckBox
            chk = CType(dgi.Cells(0).FindControl("chkSelection"), HtmlInputCheckBox)
            If chk.Checked Then
                Try
                    PageBO.RemoveOrderItem(CInt(chk.Value))
                Catch ex As Exception
                    Throw New ApplicationException("Failed to delete item " & chk.Value, ex)
                End Try
            End If
        Next

        PageBO.Save()
        Me.DataGrid1.DataSource = PageBO.OrderItems
        Me.DataGrid1.DataBind()
    End Sub

    Private Sub btnEditOrder_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnEditOrder.Click

        DisplayEditModeTemplate()

        ViewOrderDetails()
    End Sub

    Private Sub btnSaveOrder_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnSaveOrder.Click

        DisplayViewModeTemplate()

        SaveOrderDetails()
    End Sub

    Private Sub DisplayViewModeTemplate()

        lblPathName.Text = "Order Information"
        lblTitle.Text = "ORDER INFORMATION"

        trViewOrder.Visible = True
        trEditOrder.Visible = False

        btnEditOrder.Visible = True
        btnSaveOrder.Visible = False
    End Sub

    Private Sub DisplayEditModeTemplate()

        lblPathName.Text = "Edit Order Information"
        lblTitle.Text = "EDIT ORDER INFORMATION"

        trViewOrder.Visible = False
        trEditOrder.Visible = True

        btnEditOrder.Visible = False
        btnSaveOrder.Visible = True
    End Sub

#Region "   Order's data function"
    Private Sub ViewOrderDetails()

        ReloadOrderItemsDataGrid()

        InitControls()

        InitDefaultValues()
    End Sub
    Protected Function GetCustomerName() As String
        Return CUser.GetName(PageBO.CustomerID)
    End Function

    Private Sub ReloadOrderItemsDataGrid()

        Me.DataGrid1.DataSource = PageBO.OrderItems
    End Sub
    Private Sub InitControls()
        Me.ddlContainerType.DataSource = EnumToList(GetType(EContainerType))
        Me.ddlContainerType.DataTextField = "Text"
        Me.ddlContainerType.DataValueField = "Value"

        Me.ddlOrderType.DataSource = EnumToList(GetType(EOrderType))
        Me.ddlOrderType.DataTextField = "Text"
        Me.ddlOrderType.DataValueField = "Value"

        Me.ddlPackingType.DataSource = EnumToList(GetType(EPackingType))
        Me.ddlPackingType.DataTextField = "Text"
        Me.ddlPackingType.DataValueField = "Value"

        Me.ddlShippingType.DataSource = EnumToList(GetType(EShippingType))
        Me.ddlShippingType.DataTextField = "Text"
        Me.ddlShippingType.DataValueField = "Value"

        'Me.ddlOrderItemType.DataSource = EnumToList(GetType(EOrderItemType))
        'Me.ddlOrderItemType.DataTextField = "Text"
        'Me.ddlOrderItemType.DataValueField = "Value"

        Me.DataBind()
    End Sub

    Private Sub InitDefaultValues()

        Me.hidSupplierID.Value = PageBO.SupplierLkdID.ToString
        Me.hidSortRefID.Value = PageBO.SortReferenceLkdID.ToString
        Me.hidSortRefID2.Value = PageBO.SortReference2LkdID.ToString
        'Me.hidSortRangeID.Value = PageBO.SortRangeLkdID.ToString
        Me.hidDestinationPortID.Value = PageBO.DestinationPortLkdID.ToString

        Me.ddlContainerType.SelectedIndex = PageBO.ContainerType
        Me.ddlOrderType.SelectedIndex = PageBO.OrderType
        Me.ddlPackingType.SelectedIndex = PageBO.PackingType
        Me.ddlShippingType.SelectedIndex = PageBO.ShippingType
        'Me.ddlOrderItemType.SelectedIndex = Me.ddlOrderItemType.Items.IndexOf(Me.ddlOrderItemType.Items.FindByValue(PageBO.OrderItemType.ToString()))
        Me.hidCustomerID.Value = PageBO.CustomerID.ToString
        Me.hidContactID.Value = PageBO.OrderByCustomerID.ToString

        Me.radETAAsap.Checked = CType(PageBO.RequestedETA, ERequestedETAType) = ERequestedETAType.As_soon_as_possible
        Me.radETAAfter.Checked = CType(PageBO.RequestedETA, ERequestedETAType) = ERequestedETAType.After
        Me.radETABefore.Checked = CType(PageBO.RequestedETA, ERequestedETAType) = ERequestedETAType.Before
        Me.radETABetween.Checked = CType(PageBO.RequestedETA, ERequestedETAType) = ERequestedETAType.Between

        Select Case CType(PageBO.RequestedETA, ERequestedETAType)
            Case ERequestedETAType.After
                Me.txtETAAfter.Text = FormatDate(PageBO.ETADate1)
            Case ERequestedETAType.As_soon_as_possible
            Case ERequestedETAType.Before
                Me.txtETABefore.Text = FormatDate(PageBO.ETADate1)
            Case ERequestedETAType.Between
                Me.txtETAFrom.Text = FormatDate(PageBO.ETADate1)
                Me.txtETATo.Text = FormatDate(PageBO.ETADate2)
        End Select

        txtOrderNo.Text = PageBO.OrderNumber
        txtNoContainers.Text = PageBO.Containers.ToString
        txtOrderDate.Text = FormatDate(PageBO.OrderDate)
        txtGeneralShippingInstructions.Text = PageBO.ShippingInstructions

    End Sub

    Private Sub UpdateData()

        PageBO.DestinationPortLkdID = CInt(Me.hidDestinationPortID.Value)
        'PageBO.SortRangeLkdID = CInt(Me.hidSortRangeID.Value)
        PageBO.SortReferenceLkdID = CInt(Me.hidSortRefID.Value)
        PageBO.SortReference2LkdID = CInt(Me.hidSortRefID2.Value)
        PageBO.SupplierLkdID = CInt(Me.hidSupplierID.Value)
        PageBO.ContainerType = CByte(Me.ddlContainerType.SelectedIndex)
        'PageBO.OrderType = CByte(Me.ddlOrderType.SelectedIndex)
        PageBO.PackingType = CByte(Me.ddlPackingType.SelectedIndex)
        PageBO.ShippingType = CByte(Me.ddlShippingType.SelectedIndex)

        ' bulk Order also has order item type = Independent PO
        'If CType(PageBO.OrderType, EOrderType) = EOrderType.Bulk_Order Then
        '    PageBO.OrderItemType = EOrderItemType.Independent_PO
        'Else
        '    PageBO.OrderItemType = CByte(Me.ddlOrderItemType.SelectedItem.Value)
        'End If

        'PageBO.CustomerID = CInt(hidCustomerID.Value)
        PageBO.OrderByCustomerID = CInt(hidContactID.Value)

        If radETAAfter.Checked Then
            PageBO.RequestedETA = ERequestedETAType.After
            PageBO.ETADate1 = CDate(Me.txtETAAfter.Text)
        End If

        If radETAAsap.Checked Then
            PageBO.RequestedETA = ERequestedETAType.As_soon_as_possible
        End If

        If radETABefore.Checked Then
            PageBO.RequestedETA = ERequestedETAType.Before
            PageBO.ETADate1 = CDate(Me.txtETABefore.Text)
        End If

        If radETABetween.Checked Then
            PageBO.RequestedETA = ERequestedETAType.Between
            PageBO.ETADate1 = CDate(Me.txtETAFrom.Text)
            PageBO.ETADate2 = CDate(Me.txtETATo.Text)
        End If

        'PageBO.OrderNumber = txtOrderNo.Text
        PageBO.Containers = CInt(txtNoContainers.Text)
        'PageBO.OrderDate = CDate(txtOrderDate.Text)
        PageBO.ShippingInstructions = txtGeneralShippingInstructions.Text

    End Sub

    Private Sub SaveOrderDetails()
        Try
            UpdateData()

            'checking input data
            Dim objCC As New CCustomerContact
            objCC.Load(PageBO.OrderByCustomerID)

            If objCC.CustomerID <> PageBO.CustomerID Then
                Me.lblErr.Text = String.Format("The contactor <i>{0}</i> is not <i>{1}'s</i> contactor.<br>Please select another one.", Me.txtOrderBy.Text, Me.txtCustomerName.Text)
                Exit Sub
            End If

            PageBO.Save()

            'Response.Redirect(AppRoot() & Me.ORDER_LIST_URL)
        Catch ex As DataEntryException
            lblErr.Text = "Order number already exists. Please enter another one."
        Catch ex As Exception
            lblErr.Text = ex.Message
        End Try
    End Sub
#End Region

    Private Sub btnAddOI_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnAddOI.Click
        PageBO.Save()

        Me.DataGrid1.DataSource = PageBO.OrderItems
        Me.DataGrid1.DataBind()
    End Sub
End Class
